package protomsg

//BaseBinary DB上的2进制数据

func NewBinary(alen int32) *BaseBinary {
	result := new(BaseBinary)
	result.Data = make([]uint8, alen)
	result.ArrayLen = alen
	result.OneDataBitNum = 1
	return result
}
func NewBinaryByLen(alen, dlen int32) *BaseBinary {
	result := new(BaseBinary)

	result.Data = make([]uint8, alen)
	result.ArrayLen = alen
	result.OneDataBitNum = dlen
	return result
}

func (this *BaseBinary) SetArrayLen(alen int32) {
	if this.ArrayLen == alen && len(this.Data) == int(alen) {
		return
	}
	this.ArrayLen = alen
	arr := make([]uint8, alen)
	copy(arr, this.Data)
	this.Data = arr
}

func (this *BaseBinary) ContainKey(index int32) int {
	dlen := int32(this.OneDataBitNum)
	if dlen == 0 {
		return 0
	}
	ai := index / (8 / dlen)
	bitnum := uint8(index % (8 / dlen) * dlen)
	if ai >= this.ArrayLen {
		return 0
	}

	d := this.Data[ai]
	if this.OneDataBitNum == 8 {
		return int(d)
	}
	var mask uint8 = (1 << this.OneDataBitNum) - 1
	return int((d & (mask << bitnum)) >> bitnum)
}

func (this *BaseBinary) UpData(index, val int32) bool {
	bval := uint8(val)

	dlen := int32(this.OneDataBitNum)
	ai := (index / (8 / dlen))
	bitnum := uint8(index % (8 / dlen) * dlen)
	if ai >= this.ArrayLen {
		return false
	}
	key := this.Data[ai]

	if this.OneDataBitNum == 8 {
		key = bval
	} else {
		var tmp uint8 = (1 << this.OneDataBitNum) - 1
		bval = bval & tmp
		tmp = tmp << bitnum
		tmp = key & ^tmp

		key = uint8(tmp + (bval << bitnum))
	}
	this.Data[ai] = key
	return true

}

func (this *BaseBinary) ToValuesJson() []interface{} {
	dlen := int32(this.OneDataBitNum)
	result := make([]interface{}, this.ArrayLen*8/dlen)
	index := 0
	for k := int32(0); k < this.ArrayLen; k++ {
		key := this.Data[k]
		if this.OneDataBitNum == 8 {
			result[index] = key
			index++
		} else {

			for bitnum := uint8(0); bitnum < 8; bitnum = bitnum + uint8(this.OneDataBitNum) {
				var mask uint8 = (1 << this.OneDataBitNum) - 1
				result[index] = (key & (mask << bitnum)) >> bitnum
				index++
			}
		}
	}
	return result
}

func (this *BaseBinary) Clear() {
	this.Data = make([]byte, this.ArrayLen)
}
